package cn.iocoder.an.module.business.controller.admin.equipmnetkeepwait;

import cn.iocoder.an.framework.common.biz.system.permission.PermissionCommonApi;
import cn.iocoder.an.framework.common.enums.UserTypeEnum;
import cn.iocoder.an.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.an.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.an.module.business.controller.admin.keeptask.vo.KeepTaskRespVO;
import cn.iocoder.an.module.business.controller.admin.keeptask.vo.UpdateKeepWaitStatusReqVO;
import cn.iocoder.an.module.business.dal.dataobject.equipmentkeepconfig.EquipmentKeepConfigDO;
import cn.iocoder.an.module.business.dal.dataobject.keeptask.KeepTaskDO;
import cn.iocoder.an.module.business.dal.dataobject.warningconfig.WarningConfigDO;
import cn.iocoder.an.module.business.dal.mysql.equipmentkeepconfig.EquipmentKeepConfigMapper;
import cn.iocoder.an.module.business.dal.mysql.warningconfig.WarningConfigMapper;
import cn.iocoder.an.module.business.service.keeptask.KeepTaskService;
import cn.iocoder.an.module.system.enums.permission.RoleCodeEnum;
import cn.iocoder.an.module.system.service.permission.PermissionService;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.fhs.core.trans.anno.TransMethodResult;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;

import jakarta.validation.constraints.*;
import jakarta.validation.*;
import jakarta.servlet.http.*;

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.io.IOException;

import cn.iocoder.an.framework.common.pojo.PageParam;
import cn.iocoder.an.framework.common.pojo.PageResult;
import cn.iocoder.an.framework.common.pojo.CommonResult;
import cn.iocoder.an.framework.common.util.object.BeanUtils;

import static cn.iocoder.an.framework.common.pojo.CommonResult.success;

import cn.iocoder.an.framework.excel.core.util.ExcelUtils;

import cn.iocoder.an.framework.apilog.core.annotation.ApiAccessLog;

import static cn.iocoder.an.framework.apilog.core.enums.OperateTypeEnum.*;

import cn.iocoder.an.module.business.controller.admin.equipmnetkeepwait.vo.*;
import cn.iocoder.an.module.business.dal.dataobject.equipmnetkeepwait.EquipmnetKeepWaitDO;
import cn.iocoder.an.module.business.service.equipmnetkeepwait.EquipmnetKeepWaitService;

@Tag(name = "管理后台 - 待保养设备")
@RestController
@RequestMapping("/business/equipmnet-keep-wait")
@Validated
public class EquipmnetKeepWaitController {

    @Resource
    private EquipmnetKeepWaitService equipmnetKeepWaitService;

    @Resource
    private KeepTaskService keepTaskService;

    @Resource
    private PermissionService permissionService;

    @Resource
    private WarningConfigMapper warningConfigMapper;

    @Resource
    private EquipmentKeepConfigMapper equipmentKeepConfigMapper;

    @PostMapping("/create")
    @Operation(summary = "创建待保养设备")
    @PreAuthorize("@ss.hasPermission('business:equipmnet-keep-wait:create')")
    public CommonResult<Boolean> createEquipmnetKeepWait(@Valid @RequestBody EquipmnetKeepWaitSaveReqVO createReqVO) {
        equipmnetKeepWaitService.createEquipmnetKeepWait(createReqVO);
        return success(true);
    }

    @PutMapping("/update")
    @Operation(summary = "更新待保养设备")
    @PreAuthorize("@ss.hasPermission('business:equipmnet-keep-wait:update')")
    public CommonResult<Boolean> updateEquipmnetKeepWait(@Valid @RequestBody EquipmnetKeepWaitSaveReqVO updateReqVO) {
        equipmnetKeepWaitService.updateEquipmnetKeepWait(updateReqVO);
        return success(true);
    }

    @PutMapping("/updateStatus")
    @Operation(summary = "生成保养任务更新待保养数据状态")
    @PreAuthorize("@ss.hasPermission('business:keep-task:update')")
    public CommonResult<Boolean> updateKeepWaitAndInsertTask(@RequestBody UpdateKeepWaitStatusReqVO updateReqVO) {
        keepTaskService.updateKeepWaitAndInsertTask(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除待保养设备")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('business:equipmnet-keep-wait:delete')")
    public CommonResult<Boolean> deleteEquipmnetKeepWait(@RequestParam("id") Long id) {
        equipmnetKeepWaitService.deleteEquipmnetKeepWait(id);
        return success(true);
    }

    @DeleteMapping("/delete-list")
    @Parameter(name = "ids", description = "编号", required = true)
    @Operation(summary = "批量删除待保养设备")
    @PreAuthorize("@ss.hasPermission('business:equipmnet-keep-wait:delete')")
    public CommonResult<Boolean> deleteEquipmnetKeepWaitList(@RequestParam("ids") List<Long> ids) {
        equipmnetKeepWaitService.deleteEquipmnetKeepWaitListByIds(ids);
        return success(true);
    }

    @TransMethodResult
    @GetMapping("/get")
    @Operation(summary = "获得待保养设备")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('business:equipmnet-keep-wait:query')")
    public CommonResult<EquipmnetKeepWaitRespVO> getEquipmnetKeepWait(@RequestParam("id") Long id) {
        EquipmnetKeepWaitDO equipmnetKeepWait = equipmnetKeepWaitService.getEquipmnetKeepWait(id);
        KeepTaskDO keepTaskByWaitId = keepTaskService.getKeepTaskByWaitId(equipmnetKeepWait.getId());
        KeepTaskRespVO taskBean = BeanUtils.toBean(keepTaskByWaitId, KeepTaskRespVO.class);
        EquipmnetKeepWaitRespVO waitBean = BeanUtils.toBean(equipmnetKeepWait, EquipmnetKeepWaitRespVO.class);
        waitBean.setTaskRespVO(taskBean);
        return success(waitBean);
    }

    @TransMethodResult
    @GetMapping("/page")
    @Operation(summary = "获得待保养设备分页")
    @PreAuthorize("@ss.hasPermission('business:equipmnet-keep-wait:query')")
    public CommonResult<PageResult<EquipmnetKeepWaitRespVO>> getEquipmnetKeepWaitPage(@Valid EquipmnetKeepWaitPageReqVO pageReqVO) {
        PageResult<EquipmnetKeepWaitDO> pageResult = equipmnetKeepWaitService.getEquipmnetKeepWaitPage(pageReqVO);
        pageResult.getList().forEach(equipmnetKeepWaitDO -> {
            //判断是否是审核员或管理员
            Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
            boolean b = permissionService.hasAnyRoles(SecurityFrameworkUtils.getLoginUserId(), RoleCodeEnum.SUPER_ADMIN.getCode(), RoleCodeEnum.TENANT_ADMIN.getCode());
            if (b) {//判断是不是管理员
                // 是管理员 看全部信息
                equipmnetKeepWaitDO.setReviewerPermission(true);
            } else {
                KeepTaskDO keepTaskByWaitId = keepTaskService.getKeepTaskByWaitId(equipmnetKeepWaitDO.getId());
                List<Long> reviewerId = keepTaskByWaitId.getReviewerId();
                boolean isDutyUser = reviewerId != null && loginUserId != null && reviewerId.contains(loginUserId);
                equipmnetKeepWaitDO.setReviewerPermission(isDutyUser);
            }

            LocalDate planDate = equipmnetKeepWaitDO.getPlanDate();
            if (planDate != null ) {
                LocalDate today = LocalDate.now(); // 获取当前日期
                if (planDate.isAfter(today) || planDate.isEqual(today)) {
                    // planDate 大于等于今天，计算剩余天数
                    long remainingDays = ChronoUnit.DAYS.between(today, planDate);
                    equipmnetKeepWaitDO.setRemaining((int) remainingDays);
                } else {
                    // planDate 小于今天，设置为 0
                    equipmnetKeepWaitDO.setRemaining(0);
                }
                //1.先获取预警配置项 按照预警天数从大到小排序
                LambdaQueryWrapperX<WarningConfigDO> configWrapper = new LambdaQueryWrapperX<>();
                configWrapper.eq(WarningConfigDO::getWarningType, 1);
                configWrapper.orderByDesc(WarningConfigDO::getWarningDays);
                List<WarningConfigDO> configList = warningConfigMapper.selectList(configWrapper);
                if (CollectionUtils.isEmpty(configList)) {
                    return;
                }
                //根据预警规则设置对应的背景颜色
                for (WarningConfigDO config : configList) {
                    Integer warningDays = config.getWarningDays();
                    //如果剩余天数小于预警天数
                    if (equipmnetKeepWaitDO.getRemaining() <= warningDays) {
                        equipmnetKeepWaitDO.setColor(config.getWarningColor());
                    }
                }
            }

            //判断有无按设备配置过 有则itemId按照按设备配置的保养项去保养
            Long equipmentId = equipmnetKeepWaitDO.getEquipmentId();
            EquipmentKeepConfigDO equipmentKeepConfigDO = equipmentKeepConfigMapper.selectFirstOne(EquipmentKeepConfigDO::getItemId, equipmnetKeepWaitDO.getItemId(), EquipmentKeepConfigDO::getConfigType, 2, EquipmentKeepConfigDO::getTargetId, equipmentId);
            if (equipmentKeepConfigDO != null) {
                equipmnetKeepWaitDO.setItemId(equipmentKeepConfigDO.getItemId());
            }
        });
        return success(BeanUtils.toBean(pageResult, EquipmnetKeepWaitRespVO.class));
    }


    @GetMapping("/export-excel")
    @Operation(summary = "导出待保养设备 Excel")
    @PreAuthorize("@ss.hasPermission('business:equipmnet-keep-wait:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportEquipmnetKeepWaitExcel(@Valid EquipmnetKeepWaitPageReqVO pageReqVO,
                                             HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<EquipmnetKeepWaitDO> list = equipmnetKeepWaitService.getEquipmnetKeepWaitPage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "待保养设备.xls", "数据", EquipmnetKeepWaitRespVO.class,
                BeanUtils.toBean(list, EquipmnetKeepWaitRespVO.class));
    }

}